package com.android.fragmentdemo.defineviews
import android.content.Context
import android.util.AttributeSet
import android.util.SparseArray
import android.view.ViewGroup
import androidx.core.view.get
import com.android.fragmentdemo.R

class ItemsInCenterViewGroup @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null
) : ViewGroup(context, attributeSet) {

    private var defaultWidth = context.resources.getDimension(R.dimen.dp_200).toInt()
    private var defaultHeight = context.resources.getDimension(R.dimen.dp_300).toInt()

    private val viewAttrArray by lazy {
        SparseArray<ViewAttribute>()
    }

    private var viewTotalHeight = 0

    init {
        context.obtainStyledAttributes(attributeSet, R.styleable.ItemsInCenterViewGroup).apply {
            defaultWidth = getDimension(R.styleable.ItemsInCenterViewGroup_default_width, defaultWidth.toFloat()).toInt()
            defaultHeight = getDimension(R.styleable.ItemsInCenterViewGroup_default_height, defaultHeight.toFloat()).toInt()
            recycle()
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        viewTotalHeight = 0
        for (i in 0.until(childCount)) {
            val child = get(i)
            measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0)
            val viewWidth = child.measuredWidth
            val viewHeight = child.measuredHeight
            val layoutParams = child.layoutParams as MarginLayoutParams
            var viewAttr = viewAttrArray[i]
            if (viewAttr == null) {
                viewAttr = ViewAttribute(
                    viewWidth,
                    viewHeight,
                    layoutParams.leftMargin,
                    layoutParams.topMargin,
                    layoutParams.rightMargin,
                    layoutParams.bottomMargin
                )
                viewAttrArray[i] = viewAttr
            } else {
                viewAttr.viewWidth = viewWidth
                viewAttr.viewHeight = viewHeight
                viewAttr.leftMargin = layoutParams.leftMargin
                viewAttr.topMargin = layoutParams.topMargin
                viewAttr.rightMargin = layoutParams.rightMargin
                viewAttr.bottomMargin = layoutParams.bottomMargin
            }
            viewTotalHeight += viewHeight
            if (childCount > 1) {
                if (i != 0) {
                    viewTotalHeight += layoutParams.topMargin
                    if (i != childCount - 1) {
                        viewTotalHeight += layoutParams.bottomMargin
                    }
                }
            }
        }

        val mWidth = when (MeasureSpec.getMode(widthMeasureSpec)) {
            MeasureSpec.EXACTLY -> {
                MeasureSpec.getSize(widthMeasureSpec)
            }
            else -> {
                defaultWidth
            }
        } - paddingStart - paddingEnd

        val mHeight = when (MeasureSpec.getMode(heightMeasureSpec)) {
            MeasureSpec.EXACTLY -> {
                MeasureSpec.getSize(heightMeasureSpec)
            }
            else -> {
                defaultHeight
            }
        } - paddingTop - paddingBottom

        setMeasuredDimension(mWidth, mHeight)
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        var offsetY = 0
        for (i in 0.until(childCount)) {
            val child = get(i)
            val viewAttr = viewAttrArray[i]
            val viewWidth = viewAttr.viewWidth
            val viewHeight = viewAttr.viewHeight
            val topMargin = viewAttr.topMargin
            val bottomMargin = viewAttr.bottomMargin
            var margin = 0
            if (childCount > 1) {
                if (i != 0) {
                    margin += topMargin
                }
            }
            child.layout(
                width / 2 - viewWidth / 2,
                offsetY + margin + (height / 2 - viewTotalHeight / 2),
                width / 2 + viewWidth / 2,
                offsetY + viewHeight + margin + (height / 2 - viewTotalHeight / 2)
                )
            if (childCount > 1) {
                if (i != 0) {
                    if (i != childCount - 1) {
                        margin += bottomMargin
                    }
                }
            }
            offsetY += viewAttr.viewHeight + margin
        }
    }

    override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams {
        return MarginLayoutParams(context, attrs)
    }

    data class ViewAttribute(
        var viewWidth: Int,
        var viewHeight: Int,
        var leftMargin: Int,
        var topMargin: Int,
        var rightMargin: Int,
        var bottomMargin: Int
    )

    companion object {
        const val TAG = "ItemsInCenterViewGroup"
    }
}